//
//  CommentController.swift
//  用户资料页面
//  这里就不实现手机号，邮箱的更改了
//  因为他们的更改，还要进行一步验证
//  过程类似于找回密码
//  因为找回密码实现了这个流程
//  这里这里就不再重复实现了
//
//  Created by smile on 2019/4/13.
//  Copyright © 2019 ixuea. All rights reserved.
//

import UIKit

// 键盘管理器
// 目的是键盘弹出时
// 相应的控件自动上移避免挡住
import KeyboardLayoutGuide

//TextView实现提示文字框架
import KMPlaceholderTextView

//发布订阅框架
import SwiftEventBus

//下拉刷新
//上拉加载更多
import ESPullToRefresh

class CommentController: BaseTitleController {
    // MARK: - 控件
    
    /// 评论列表显示控件
    @IBOutlet weak var tableView: UITableView!
    
    /// 文本输入框
    @IBOutlet weak var textView: KMPlaceholderTextView!
    
    /// 输入框边框
    @IBOutlet weak var vwInputBorder: UIView!
    
    /// 输入框最外层容器
    @IBOutlet weak var vwInputContainer: UIView!
    
    // MARK: - 变量
    /// 歌单Id
    var sheet_id:String?
    
    /// 被回复评论的Id
    var parent_id:String?
    
    /// 当前界面列表数据
    var dataArray:[CommentGroup]=[]
    
    var meta:Meta?
    
    // MARK: - 初始化方法
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
    
    override func initViews() {
        super.initViews()
        
        setTitle("评论")
        
        //设置输入框圆角
        ViewUtil.showSmallRadius(view: vwInputBorder)
        
        //设置输入框边框
        vwInputBorder.showColorPrimaryBorder()

        //自定义section
        //因为默认的UI不太适合我们
        //所以真实项目中大部分情况都要自定义

        //注册评论标题Cell
        tableView.register(UINib(nibName: CommentHeaderView.NAME, bundle: nil), forHeaderFooterViewReuseIdentifier: CommentHeaderView.NAME)
        
        //注册评论Cell
        tableView.register(UINib(nibName: CommentCell.NAME, bundle:nil), forCellReuseIdentifier: CommentCell.NAME)

        //设置高度为自动计算
        //如果没有在可视化中设置Cell为固定高度
        //可以不用在代码中设置自动计算
        //因为这是默认的行为
//        tableView.rowHeight = UITableView.automaticDimension
//
//        //预估高度
//        tableView.estimatedRowHeight = 200.0
        
        //添加一条自动布局约束
        //含义是：输入框的底部锚点
        //等于当前界面中View的底部锚点
        //也就说这个框架
        vwInputContainer.bottomAnchor.constraint(equalTo: view.keyboardLayoutGuide.topAnchor).isActive = true
    }
    
    override func initDatas() {
        super.initDatas()
        
        fetchData()
    }
    
    override func initListeners() {
        super.initListeners()
        
        //设置下拉刷新回调
        tableView.es.addPullToRefresh {
            self.dataArray.removeAll()

            //调用加载数据的方法
            self.fetchData()
        }

        //设置上拉回调
        self.tableView.es.addInfiniteScrolling {
            self.loadMore()
        }
        
        //设置代理
        textView.delegate=self
        
        //监听选择了话题
        SwiftEventBus.onMainThread(self, name: SELECT_TOPIC) { result in
            let data = result!.object as! Topic
            
            let source=self.textView.text.trim()
            
            //格式最终字符串
            let result="\(source!)#\(data.title!)#"
            
            //设置到输入框
            self.setText(result)
        }
        
        //监听选择了好友
        SwiftEventBus.onMainThread(self, name: SELECT_FRIEND) { result in
            let data = result!.object as! User
            
            let source=self.textView.text.trim()
            
            //格式最终字符串
            let result="\(source!)@\(data.nickname!) "
            
            //设置到输入框
            self.setText(result)
        }
    }
    
    func setText(_ data:String) {
        //高亮
        let result=StringUtil.processHighlight(data)
        
        textView.attributedText=result
        
        //将光标移动最后
//        textView
//        setSelectedRange:NSMakeRange(str.length,0)];
    }
    
    /// 加载首页数据
    func fetchData() {
        //将分页对象设置空
        //这样在加载更多的方法中
        //就会获取第一页评论
        meta=nil

        //清除原来集合的数据
        dataArray.removeAll()

        //热门评论
        Api.shared
            .comments(sheet_id: sheet_id, order: ORDER_HOT)
            .subscribeOnSuccess { baseResponse in
            if let data=baseResponse?.data {
                //刷新完成
                self.tableView.es.stopPullToRefresh()
                
                let commentGroup=CommentGroup()
                commentGroup.title="精彩评论"
                commentGroup.comments = data
                
                self.dataArray.append(commentGroup)
                
                //先创建一个空数组，最新的评论，添加到该列表
                let newCommentGroup=CommentGroup()
                newCommentGroup.title="最新评论"
                newCommentGroup.comments = []
                
                self.dataArray.append(newCommentGroup)
                
                //加载更多(最新评论)
                self.loadMore()
            }
        }.disposed(by: disposeBag)
        
    }

    func loadMore()  {
        //最新评论
        //第一次为空，但因为服务端不传递page，就默认是第一页
        //所有这种方式没问题
        let page=Meta.nextPage(meta)
        
        Api.shared
            .comments(sheet_id: sheet_id,page: page)
            .subscribeOnSuccess { baseResponse in
                if let data=baseResponse?.data {
                    //分页数据
                    self.meta=baseResponse!.meta
                    
                    //设置标题
                    self.setTitle("评论(\(self.meta!.total_count))")
                    
                    //取出原来的数组
                    let newCommentGroup=self.dataArray[1]
                    
                    //添加进去
                    newCommentGroup.comments = newCommentGroup.comments+data
                    
                    //通知界面刷新
                    self.tableView.reloadData()
                    
                    
                    //判断是否加载完毕，控制是否还可以上拉
                    if self.meta!.next_page != nil {
                        //还有数据可加载
                        self.tableView.es.stopLoadingMore()
                    }else{
                        //数据加载完了
                        self.tableView.es.noticeNoMoreData()
                        
                    }
                }
        }.disposed(by: disposeBag)
       
    }

    
    /// 评论点赞
    ///
    /// - Parameter comment: <#comment description#>
    func onLikeClick(_ comment:Comment) {
        //这里的点赞逻辑和歌单详情的收藏差不多
        if comment.isLiked() {
            //已经点赞，取消
            
            //取消点赞
            //传递的是这条关系的Id
            Api.shared
                .deleteLike(comment.like_id!)
                .subscribeOnSuccess { (data) in
                //可以调用接口，也可以在本地加减
                //但本地加减，效率更高
                comment.like_id = nil
                comment.likes_count -= 1
                
                //重新刷新数据
                //也可以直接获取到这个Cell
                //直接更改Cell
                //这样理论上效率高一点
                self.tableView.reloadData()
                
            }.disposed(by: disposeBag)
            
        } else {
            //点赞
            Api.shared
                .like(comment.id)
                .subscribeOnSuccess { (data) in
                    //将点赞返回的Id设置到对象上
                    comment.like_id = data!.data!.id
                    comment.likes_count += 1
                    
                    self.tableView.reloadData()
            
            }.disposed(by: disposeBag)
            
        }
        
    }
    
    /// 评论中用户头像点击事件
    ///
    /// - Parameter data: <#data description#>
    func onAvatarClick(_ data:User) {
        UserDetailController.start(self.navigationController!, userId: data.id)
    }
    
    /// 打开选择好友界面
    func selectFriend() {
        SelectFriendController.start(navigationController!)
    }
    
    /// 打开选择话题界面
    func selectTopic() {
        SelectTopicController.start(self.navigationController!)
    }

    // MARK: - 发送评论
    /// 发送评论
    func sendComment() {
        let content=textView.text!.trim()
        if content!.isEmpty {
            ToastUtil.short("请输入评论.")
            
            return
        }
        
        Api.shared
            .createComment(content: content!, sheet_id: sheet_id, parent_id: parent_id).subscribeOnSuccess { (data) in
                //清除输入的内容，和回复评论
                self.clearReplyComment()
                
                //隐藏键盘
                //要先隐藏键盘
                //在请求数据
                //因为隐藏键盘的时候
                //TableView的布局会变动
                //而我们在fetchData方法中清除了数组的数据
                //会导致TableView刷新是报错
                self.hideKeyboard()
                
                //重新设置最热评论
                //然后在拉去第一页评论
                //当然也可以手动将发送的评论插入到数组中
                self.fetchData()
                
        }.disposed(by: disposeBag)
    }

    func clearReplyComment() {
        setPlaceholder()
        textView.text=""
        parent_id = nil
    }
    
    func hideKeyboard() {
        //隐藏键盘
        textView.resignFirstResponder()
        
    }

    /// 设置提示文本
    func setPlaceholder() {
        textView.placeholder="人生苦短，我们只做好课！"
    }
    
    //滑动中
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        //滑动中,如果没有输入内容，就清除恢复，隐藏键盘
        //当然也可以判断，例如：滚动记录达到了一个阈值
        let content=textView.text.trim()
        if content!.isEmpty {
            clearReplyComment()
            hideKeyboard()
        }
    }
    
    
    /// 评论更多对话框
    ///
    /// - Parameter data: <#data description#>
    func showCommentMoreDialog(_ data:Comment) {
        let controller=UIAlertController(title: nil, message: nil, preferredStyle: UIAlertController.Style.actionSheet)
        
        //回复评论
        let replyAction=UIAlertAction(title: "回复", style: UIAlertAction.Style.default) { (action) in
            print("CommentController reply comment:\(data.content)")
            
            self.parent_id = data.id;
            self.textView.placeholder="回复\(data.user.nickname!): "
        }
        
        //分享
        let shareAction=UIAlertAction(title: "分享", style: .default) { (action) in
            print("CommentController share comment:\(data.content)")
            
        }
        
        //拷贝评论内容到剪贴板
        let copyAction=UIAlertAction(title: "复制", style: .default) { (action) in
            print("CommentController copy comment:\(data.content)")
            
            //拷贝评论内容到剪贴板
            let pasteboard = UIPasteboard.general
            pasteboard.string = data.content
            
            ToastUtil.short("拷贝成功！")
        }
        
        var lastAction:UIAlertAction? = nil
        
        //这里只进行了简单判断
        //例如：用户未登陆，该动作怎么处理
        //具体的就是业务逻辑了
        //现在的实现是当前评论是自己的
        //就是显示删除
        //如果不是就是举报
        
        if  PreferenceUtil.userId() != nil &&  PreferenceUtil.userId()! == data.user!.id.description  {
            //自己发布的评论
            //显示删除按钮
            lastAction=UIAlertAction(title: "删除", style: .default, handler: { (action) in
                print("CommentController delete comment:\(data.content)")
            })
        } else {
            //其他人发布的评论
            //显示举报按钮
            lastAction=UIAlertAction(title: "举报", style: .default, handler: { (action) in
                print("CommentController report comment:\(data.content)")
            })
        }
        
        //把action添加到控制器中
        controller.addAction(replyAction)
        controller.addAction(shareAction)
        controller.addAction(copyAction)
        controller.addAction(lastAction!)
        
        //在最后添加一个取消按钮
        controller.addAction(UIAlertAction(title: "取消", style: .cancel, handler: nil))
        
        //显示控制器
        present(controller, animated: true, completion: nil)
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}

// MARK: - 启动界面
extension CommentController {
    
    /// 启动界面
    ///
    /// - Parameters:
    ///   - navigationController: <#navigationController description#>
    ///   - sheet: 歌单Id
    static func start(_ navigationController:UINavigationController,sheet:String) {
        //创建控制器
        let controller=navigationController.storyboard?.instantiateViewController(withIdentifier: "Comment") as! CommentController
        
        controller.sheet_id=sheet
        
        //将控制器压入导航控制中
        navigationController.pushViewController(controller, animated: true)
        
    }
}

// MARK:- TableView数据源
extension CommentController:UITableViewDataSource,UITableViewDelegate{
    
    
    /// 返回有多少组
    ///
    /// - Parameter tableView: <#tableView description#>
    /// - Returns: <#return value description#>
    func numberOfSections(in tableView: UITableView) -> Int {
        return dataArray.count
    }
    
    /// 返回有多个条目
    /// 和CollectionView差不多
    ///
    /// - Parameters:
    ///   - tableView: tableView description
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let commentGroup = dataArray[section]
        return commentGroup.comments.count
    }
    
    /// 返回当前位置的Cell
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - indexPath: <#indexPath description#>
    /// - Returns: <#return value description#>
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //获取Cell
        let cell=tableView.dequeueReusableCell(withIdentifier: CommentCell.NAME, for: indexPath) as! CommentCell
        
        //设置Tag
        //目的是Cell中显示位置
        //还有点击Cell更多按钮时知道是点击了那个Cell
        //        cell.tag=indexPath.row
        
        let data=dataArray[indexPath.section]
        
        let comment = data.comments[indexPath.row]
        
        cell.bindData(comment)
        
        //点赞回调
        cell.onLikeClick={
            data in
            self.onLikeClick(data)
        }
        
        //评论用户头像点击回调
        cell.onAvatarClick={
            data in
            self.onAvatarClick(data)
        }
        
        //昵称点击回调
        cell.onNicknameClick={
            data in
            print("CommentController onNicknameClick:\(data)")
            
            UserDetailController.start(self.navigationController!, nickname: data)
        }
        
        //话题点击回调
        cell.onHashTagClick={
            data in
            print("CommentController onHashTagClick:\(data)")
            
            TopicDetailController.start(self.navigationController!,title:data)
        }
        
        return cell
    }
    
    /// Item点击事件
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - indexPath: <#indexPath description#>
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("CommentController didSelectRowAt:\(indexPath.row)")
        //取出数据
        let commentGroup = dataArray[indexPath.section]
        let data=commentGroup.comments[indexPath.row]
        
        //显示更多对话框
        showCommentMoreDialog(data)
        
    }
    
    
    /// 返回section标题
    /// 可以自定义
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    //    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    //        let commentGroup = dataArray[section]
    //        return commentGroup.title
    //    }
    
    
    /// 返回自定义的section(header)
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let cell=tableView.dequeueReusableHeaderFooterView(withIdentifier: CommentHeaderView.NAME) as! CommentHeaderView
        
        let commentGroup = dataArray[section]
        
        cell.bindData(commentGroup.title)
        
        return cell
    }
    
}

// MARK: - 文本监听
extension CommentController:UITextViewDelegate{
    
    /// 当前文本改变时调用
    ///
    /// - Parameters:
    ///   - textView: <#textView description#>
    ///   - range: <#range description#>
    ///   - text: <#text description#>
    /// - Returns: <#return value description#>
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        print("comment controller shouldChangeTextInRange:\(text)")
        
        //判断输入的字是否是回车，即按下return
        if text=="\n" {
            //return按钮
            print("return click:\(text)")
            
            self.sendComment()
            
            //这里返回false，就代表return键值失效
            //即页面上按下return，不会出现换行
            //如果为true，则输入页面会换行
            //但是如果想用return发送
            //但又想实现换行，就无法实现了
            return false
        }else if text=="@" {
            //选择人
            print("select friend")
            
            self.selectFriend()
            
            //返回false后输入框就不会有@
            //所以需要选择人后手动添加前面的@符号
            
            //如果这里返回true
            //实现的效果就是如果不选择人
            //直接关闭选择好友界面
            //输入框中会有@
            //具体那种实现看需求
            return false
        }else if text == "#" {
            //选择话题
            print("select topic")
            self.selectTopic()
            
            return false
        }
        
        //其他情况返回true
        //表示其他字符正常输入
        return true
    }
    
}
